package com.shanxi.cz.framework.common.util.calculate;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.util.List;

public class AverageUtils {

    /**
     * 计算三个数的平均值 - 多种方式
     */
    public static class AverageResult {
        private final double num1;
        private final double num2;
        private final double num3;
        private final double average;
        private final String formatted;

        public AverageResult(double num1, double num2, double num3,
                             double average, String formatted) {
            this.num1 = num1;
            this.num2 = num2;
            this.num3 = num3;
            this.average = average;
            this.formatted = formatted;
        }

        // Getters
        public double getAverage() {
            return average;
        }

        public String getFormatted() {
            return formatted;
        }

        public double getNum1() {
            return num1;
        }

        public double getNum2() {
            return num2;
        }

        public double getNum3() {
            return num3;
        }
    }

    /**
     * 计算平均值（BigDecimal方式 - 最精确）
     */
    public static BigDecimal calculateExactAverage(double num1, double num2, double num3) {
        BigDecimal bd1 = BigDecimal.valueOf(num1);
        BigDecimal bd2 = BigDecimal.valueOf(num2);
        BigDecimal bd3 = BigDecimal.valueOf(num3);

        BigDecimal sum = bd1.add(bd2).add(bd3);
        return sum.divide(BigDecimal.valueOf(3), 4, RoundingMode.HALF_UP);
    }

    public static Double calculateExactAverageD(double num1, double num2, double num3) {
        BigDecimal bd1 = BigDecimal.valueOf(num1);
        BigDecimal bd2 = BigDecimal.valueOf(num2);
        BigDecimal bd3 = BigDecimal.valueOf(num3);

        BigDecimal sum = bd1.add(bd2).add(bd3);
        BigDecimal divide = sum.divide(BigDecimal.valueOf(3), 4, RoundingMode.HALF_UP);
        return divide.doubleValue();
    }

    /**
     * 使用BigDecimal计算不确定个数的平均值（高精度）
     */
    public static BigDecimal calculateAverage(BigDecimal... numbers) {
        if (numbers == null || numbers.length == 0) {
            throw new IllegalArgumentException("数字数组不能为空");
        }

        BigDecimal sum = BigDecimal.ZERO;
        for (BigDecimal num : numbers) {
            sum = sum.add(num);
        }

        BigDecimal count = new BigDecimal(numbers.length);
        return sum.divide(count, 6, RoundingMode.HALF_UP)
                .setScale(4, RoundingMode.HALF_UP);
    }

    /**
     * 重载方法，支持double类型参数
     */
    public static Double calculateAverageD(double... numbers) {
        if (numbers == null || numbers.length == 0) {
            throw new IllegalArgumentException("数字数组不能为空");
        }

        BigDecimal sum = BigDecimal.ZERO;
        for (double num : numbers) {
            sum = sum.add(BigDecimal.valueOf(num));
        }

        BigDecimal count = new BigDecimal(numbers.length);
        BigDecimal bigDecimal = sum.divide(count, 6, RoundingMode.HALF_UP)
                .setScale(4, RoundingMode.HALF_UP);
        return bigDecimal.doubleValue();
    }

    /**
     * 支持Double列表
     */
    public static BigDecimal calculateAverageFromDouble(List<Double> numbers) {
        if (numbers == null || numbers.isEmpty()) {
            throw new IllegalArgumentException("数字列表不能为空");
        }

        BigDecimal sum = numbers.stream()
                .map(BigDecimal::valueOf)
                .reduce(BigDecimal.ZERO, BigDecimal::add);

        BigDecimal count = new BigDecimal(numbers.size());
        return sum.divide(count, 6, RoundingMode.HALF_UP)
                .setScale(4, RoundingMode.HALF_UP);
    }

    /**
     * 计算平均值（四舍五入方式）
     */
    public static double calculateAverage(double num1, double num2, double num3) {
        double average = (num1 + num2 + num3) / 3;
        return Math.round(average * 10000.0) / 10000.0;
    }

    /**
     * 格式化平均值输出
     */
    public static String formatAverage(double num1, double num2, double num3) {
        double average = (num1 + num2 + num3) / 3;
        return String.format("%.4f", average);
    }

    /**
     * 完整的平均值计算结果
     */
    public static AverageResult calculateAverageResult(double num1, double num2, double num3) {
        BigDecimal exactAverage = calculateExactAverage(num1, num2, num3);
        double averageValue = exactAverage.doubleValue();
        String formatted = exactAverage.toString();

        return new AverageResult(num1, num2, num3, averageValue, formatted);
    }

    /**
     * 批量计算多个三元组的平均值
     */
    public static void batchCalculate(double[][] numberTriples) {
        DecimalFormat df = new DecimalFormat("0.0000");

        for (int i = 0; i < numberTriples.length; i++) {
            if (numberTriples[i].length == 3) {
                double average = calculateAverage(
                        numberTriples[i][0],
                        numberTriples[i][1],
                        numberTriples[i][2]
                );
                System.out.printf("第%d组: (%.2f, %.2f, %.2f) 平均值: %s\n",
                        i + 1, numberTriples[i][0], numberTriples[i][1],
                        numberTriples[i][2], df.format(average));
            }
        }
    }

    public static void main(String[] args) {
        // 测试各种情况
        double[][] testCases = {
                {1.1111, 2.2222, 3.3333},    // 精确除尽
                {10.1234, 20.5678, 30.9999}, // 需要四舍五入
                {1.0, 2.0, 3.0},             // 整数
                {1.55555, 2.66666, 3.77777}  // 多位小数
        };

        System.out.println("=== 平均值计算测试 ===");
        for (int i = 0; i < testCases.length; i++) {
            AverageResult result = calculateAverageResult(
                    testCases[i][0], testCases[i][1], testCases[i][2]);

            System.out.printf("数字: %.5f, %.5f, %.5f\n",
                    result.getNum1(), result.getNum2(), result.getNum3());
            System.out.printf("平均值: %s (精确值: %.8f)\n\n",
                    result.getFormatted(), result.getAverage());
        }

        System.out.println("=== 批量计算 ===");
        batchCalculate(testCases);
    }
}